
/* -----------------
* brief 
* 1. this is code gen by tools 
* 2. for add/update/delete/query the data save in sql database   
*/

package merchantCard

import (
	"fmt"
	"github.com/go-xorm/xorm"
	"github.com/mjiulee/lego"
	"github.com/mjiulee/lego/utils"
	"saas_sys_base/common"
	//"github.com/mjiulee/lego/utils"
)

/* 根据id获取记录
 * -----------------
 */
func (t *MchUserMemberCard) RecodeById(id int64) *MchUserMemberCard {
	item := new(MchUserMemberCard)
	lego.GetDBEngine().ID(id).Where("if_del = ?", 0).Get(item)
	if item.Id <= 0 {
		return nil
	}
	return item
}

func (t *MchUserMemberCard) ReocodeByWeappIdCardIdAndCardCode(weappid string, wxCardId string, cardcode string) *MchUserMemberCard {
	item := new(MchUserMemberCard)
	item.WeappId = weappid
	item.WxCardId = wxCardId
	item.UserCardCode = cardcode
	lego.GetDBEngine().Where("if_del = ?", 0).Get(item)
	if item.Id <= 0 {
		return nil
	}
	return item
}

func (t *MchUserMemberCard) RecodeByIdWithsession(session*xorm.Session, id int64) *MchUserMemberCard {
	item := new(MchUserMemberCard)
	session.ID(id).Where("if_del = ?", 0).Get(item)
	if item.Id <= 0 {
		return nil
	}
	return item
}

/* 添加
 * -----------------
 */
func (t *MchUserMemberCard) AddRecode(item2add *MchUserMemberCard) bool {
	item2add.Id = lego.UUID()
	if item2add.UserCardCode == "" {
		//userCardCode、weappid、WxCardId字段配置为unique组，所以当纯商户卡模式时
		//这组值都是空，所以商户卡模式是给userCardCode进行赋值，避免add失败
		item2add.UserCardCode = utils.Int64ToString(item2add.Id)
	}

	_, err := lego.GetDBEngine().Insert(item2add)
	if err != nil {
		lego.LogError(err)
		return false
	}
	return true
}

func (t *MchUserMemberCard) AddRecodeWithsession(session*xorm.Session,item2add *MchUserMemberCard) bool {
	item2add.Id = lego.UUID()
	if item2add.UserCardCode == "" {
		//userCardCode、weappid、WxCardId字段配置为unique组，所以当纯商户卡模式时
		//这组值都是空，所以商户卡模式是给userCardCode进行赋值，避免add失败
		item2add.UserCardCode = utils.Int64ToString(item2add.Id)
	}
	_, err := session.Insert(item2add)
	if err != nil {
		lego.LogError(err)
		return false
	}
	return true
}

/* 删除(软删除)
 * -----------------
 */
func (t *MchUserMemberCard) SDelRecodeById(id int64) bool {
	item := new(MchUserMemberCard)
	item.IfDel = 1
	_, err := lego.GetDBEngine().ID(id).Update(item)
	if err == nil {
		return true
	}
	return false
}

func (t *MchUserMemberCard) SDelRecodeByIdWithSession(session*xorm.Session, id int64) bool {
	item := new(MchUserMemberCard)
	item.IfDel = 1
	_, err := session.ID(id).Update(item)
	if err == nil {
		return true
	}
	return false
}

func (t *MchUserMemberCard) SDelRecodeByWeappIdCardIdAndCardCode(weappid string, cardid string, cardcode string) bool {
	item := new(MchUserMemberCard)
	item.IfDel = 1
	_, err := lego.GetDBEngine().Where("weapp_id = ?", weappid).
		And("wx_card_id", cardid).
		And("user_card_code", cardcode).Update(item)
	if err == nil {
		return true
	}
	return false
}

/* 删除(硬删除)*/
/*func (t *MchUserMemberCard) DelRecodeById(id int64) bool {
	item := new(MchUserMemberCard)
	_, err := lego.GetDBEngine().ID(id).Delete(item)
	if err != nil {
        lego.LogError(err)
        return false
    }
    return true
}

func (t *MchUserMemberCard) DelRecodeByIdWithSession(session*xorm.Session,id int64) bool {
	item := new(MchUserMemberCard)
	_, err := session.ID(id).Delete(item)
	if err != nil {
        lego.LogError(err)
        return false
    }
    return true
}*/

/* 更新
 * -----------------*/
func (t *MchUserMemberCard) UpdateRecode(rc *MchUserMemberCard, columns... string) (int64, error) {
	if len(columns) == 0 {
		rc.Balance = 0 //余额需要显式指定才会更新，否则不予以更新
		rc.Bonus = 0
	}
	affectedRows, err := lego.GetDBEngine().Id(rc.Id).Cols(columns...).Update(rc)
	if err != nil {
		lego.LogError(err)
		return affectedRows, err
	}

	return affectedRows, err
}



/*func (t *MchUserMemberCard) UpdateRecodecLockWithSession(session *xorm.Session,rc *MchUserMemberCard) (int64, error) {
	oldlock := rc.Lock
	//rc.Lock += lego.UUID()
	rc.Lock += 1
	affectedRows, err := session.ID(rc.Id).Where("lock = ?", oldlock).Update(rc)
	if err != nil {
		lego.LogError(err)
		return affectedRows, err
	}

	if affectedRows == 0 {
		rc.Lock = oldlock //如果乐观锁更新失败，则恢复原乐观锁的值，防止外部未再次在未读取记录的情况下重复调用update，可能会使乐观锁失效
	}

	return affectedRows, err
}*/


func (t *MchUserMemberCard) UpdateRecodeWithSession(session *xorm.Session,rc *MchUserMemberCard, columns... string) (int64, error) {
	if len(columns) == 0 {
		rc.Balance = 0 //余额需要显式指定才会更新，否则不予以更新
		rc.Bonus = 0
	}

	affectedRows, err := session.ID(rc.Id).Cols(columns...).Update(rc)
	if err != nil {
        lego.LogError(err)
        return affectedRows, err
    }

    return affectedRows, err
}

func (t *MchUserMemberCard) UpdateRecodeByWeappIdCardIdAndCardCode(rc *MchUserMemberCard, weappid string, cardid string, cardcode string, columns... string) bool {
	if len(columns) == 0 {
		rc.Balance = 0 //余额需要显式指定才会更新，否则不予以更新
		rc.Bonus = 0
	}

	_, err := lego.GetDBEngine().Where("weapp_id = ?", weappid).
		And("wx_card_id", cardid).
		And("user_card_code", cardcode).Cols(columns...).
		Update(rc)
	if err != nil {
		lego.LogError(err)
		return false
	}
	return true
}

//计算指定的用户领了多少张指定的卡
//这里没有以userWho为筛选条件，这个没考虑好，根据调用此函数的场景吧
func (t *MchUserMemberCard) CountByMchCardIdAndUid(mchCardId int64, uid int64) (int64, error) {
	item := new(MchUserMemberCard)
	//根据结构体中已有的非空数据来获得单条数据
	item.MchCardId = mchCardId
	item.Who.Uid = uid
	count, err := lego.GetDBEngine().Where("if_del = ?", 0).Count(item)//Get(item)
	if err != nil {
		return 0, err
	}
	return count, err
}


func (t *MchUserMemberCard) ListMchUserMemberCardByTenant(tid int64, keyword string, orderfiled, order string, page, psize int) ([]MchUserMemberCard, int64, error) {
	start := (page-1*psize)
	resultList := make([]MchUserMemberCard, 0)


	if order != common.ORDER_NULL && order != common.ORDER_ASC && order != common.ORDER_DESC {
		return nil, 0, fmt.Errorf("not support order<%s>", order)
	}

	session := lego.GetDBEngine().Table(MchUserMemberCard{}).Alias("t1").
		Join("INNER", []string{TB_MCH_MEMBER_CARD, "t2"}, "t2.id = t1.mch_card_id").
		//Join("INNER", "tb_xx", "tb_xx.id = tb_xx.type_id").
		Where("t1.if_del = ?", 0).And("t2.if_del = ?", 0).
		And("t1.tenant_id = ?", tid)

	//OrderBy("asc")

	//排序
	if orderfiled == MEMBER_LIST_ORDER_FEILD_RENENTLY_ARRIVED { //最近到店
		session = session.OrderBy("udate desc")
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_MEMBER_LEVEL_NO { //按会员等级
		orderStr := "member_level_no " + order
		session = session.OrderBy(orderStr)
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_PREMIUM_MEMBER { //按优质会员排序
		session = session.OrderBy("udate desc")
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_BIRTHDAY_IN_30_DAYS { //30天内生日
        session = session.Where("date_format( birthday , '%m%d' ) BETWEEN date_format( now() , '%m%d' ) AND date_format( date_add( now( ) , INTERVAL 30 DAY ) , '%m%d' ) ")
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_NOT_ARRIVED_IN_30_DAYS { //30天内未来的
		session = session.Where("date_format( udate , '%y%m%d' ) < date_format( date_sub( now( ) , INTERVAL 30 DAY ) , '%y%m%d' )")
	}


	if len(keyword) > 0 {
		keyword = "%" + keyword + "%"
		session = session.Where("t1.user_name like ? Or t1.phone like ? Or t1.id like ?", keyword, keyword, keyword) //t1.id为用户卡卡号
	}

	session2 := *session.Clone()
	err := session.Limit(psize, start).Find(&resultList)
	if err != nil {
		return nil, 0, err
	}

	total, err := session2.Count()
	if err != nil {
		return nil, 0, err
	}
	return resultList, total, err
}

func (t *MchUserMemberCard) ListMchUserMemberCardByMchCardId(mchCardId int64, keyword string, orderfiled, order string, page, psize int) ([]MchUserMemberCard, int64, error) {
	start := (page-1*psize)
	resultList := make([]MchUserMemberCard, 0)


	if order != common.ORDER_NULL && order != common.ORDER_ASC && order != common.ORDER_DESC {
		return nil, 0, fmt.Errorf("not support order<%s>", order)
	}

	session := lego.GetDBEngine().Table(MchUserMemberCard{}).Alias("t1").
		//Join("INNER", []string{TB_MCH_MEMBER_CARD, "t2"}, "t2.id = t1.group_id").
		//Join("INNER", "tb_xx", "tb_xx.id = tb_xx.type_id").
		Where("if_del = ?", 0).
		And("mch_card_id = ?", mchCardId)

	//OrderBy("asc")

	//排序
	if orderfiled == MEMBER_LIST_ORDER_FEILD_RENENTLY_ARRIVED { //最近到店
		session = session.OrderBy("udate desc")
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_MEMBER_LEVEL_NO { //按会员等级
		orderStr := "member_level_no " + order
		session = session.OrderBy(orderStr)
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_PREMIUM_MEMBER { //按优质会员排序
		session = session.OrderBy("udate desc")
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_BIRTHDAY_IN_30_DAYS { //30天内生日
		session = session.Where("date_format( birthday , '%m%d' ) BETWEEN date_format( now() , '%m%d' ) AND date_format( date_add( now( ) , INTERVAL 30 DAY ) , '%m%d' ) ")
	} else if orderfiled == MEMBER_LIST_ORDER_FEILD_NOT_ARRIVED_IN_30_DAYS { //30天内未来的
		session = session.Where("date_format( udate , '%y%m%d' ) < date_format( date_sub( now( ) , INTERVAL 30 DAY ) , '%y%m%d' )")
	}


	if len(keyword) > 0 {
		keyword = "%" + keyword + "%"
		session = session.Where("t1.user_name like ? Or t1.phone like ? Or t1.id like ?", keyword, keyword, keyword) //t1.id为用户卡卡号
	}

	session2 := *session.Clone()
	err := session.Limit(psize, start).Find(&resultList)
	if err != nil {
		return nil, 0, err
	}

	total, err := session2.Count()
	if err != nil {
		return nil, 0, err
	}
	return resultList, total, err
}